Bug 2375150 - u-boot tools build broken after recent termios changes
Summary: u-boot tools build broken after recent termios changes
Keywords:
Status: ASSIGNED
Alias: None
Product: Fedora
Classification: Fedora
Component: uboot-tools
Version: rawhide
Hardware: ppc64le
OS: Linux
unspecified
medium
Target Milestone: ---
Assignee: Peter Robinson
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: PPCTracker
TreeView+ depends on / blocked
 
Reported: 2025-06-27 09:25 UTC by Dan Horák
Modified: 2025-07-01 23:20 UTC (History)
23 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Dan Horák 2025-06-27 09:25:24 UTC
Seems the recent termios related changes broke the build of some u-boot tools on ppc64le. Please see build log from https://koji.fedoraproject.org/koji/taskinfo?taskID=134460943 for all details. https://github.com/u-boot/u-boot/blob/master/tools/termios_linux.h is the u-boot file broken.

..
  gcc -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -Wp,-MD,tools/.kwboot.d -Itools -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -DCONFIG_FIT_SIGNATURE -DCONFIG_FIT_SIGNATURE_MAX_SIZE=0xffffffff -DCONFIG_FIT_CIPHER -include ../include/compiler.h -idirafterinclude -idirafter../include -idirafter../arch/sandbox/include -idirafter../dts/upstream/include  -I../scripts/dtc/libfdt  -I../tools -DUSE_HOSTCC -D__KERNEL_STRICT_NAMES -D_GNU_SOURCE -pthread   -o tools/kwboot ../tools/kwboot.c   -pthread -ltinfo
In file included from ../tools/kwboot.c:153:
../tools/termios_linux.h:36:17: warning: ‘struct termios2’ declared inside parameter list will not be visible outside of this definition or declaration
   36 | #define termios termios2
      |                 ^~~~~~~~
../tools/termios_linux.h:39:44: note: in expansion of macro ‘termios’
   39 | static inline int tcgetattr(int fd, struct termios *t)
      |                                            ^~~~~~~
In file included from /usr/include/asm/ioctl.h:12,
                 from /usr/include/asm/ioctls.h:5,
                 from /usr/include/bits/ioctls.h:23,
                 from /usr/include/sys/ioctl.h:26,
                 from ../tools/termios_linux.h:30:
../tools/termios_linux.h: In function ‘tcgetattr’:
../tools/termios_linux.h:42:26: error: invalid application of ‘sizeof’ to incomplete type ‘struct termios2’
   42 |         return ioctl(fd, TCGETS2, t);
      |                          ^~~~~~~
../tools/termios_linux.h: At top level:
../tools/termios_linux.h:36:17: warning: ‘struct termios2’ declared inside parameter list will not be visible outside of this definition or declaration
   36 | #define termios termios2
      |                 ^~~~~~~~
../tools/termios_linux.h:48:57: note: in expansion of macro ‘termios’
   48 | static inline int tcsetattr(int fd, int a, const struct termios *t)
      |                                                         ^~~~~~~
../tools/termios_linux.h: In function ‘tcsetattr’:
../tools/termios_linux.h:55:23: error: invalid application of ‘sizeof’ to incomplete type ‘struct termios2’
   55 |                 cmd = TCSETS2;
      |                       ^~~~~~~
../tools/termios_linux.h:58:23: error: invalid application of ‘sizeof’ to incomplete type ‘struct termios2’
   58 |                 cmd = TCSETSW2;
      |                       ^~~~~~~~
../tools/termios_linux.h:61:23: error: invalid application of ‘sizeof’ to incomplete type ‘struct termios2’
   61 |                 cmd = TCSETSF2;
      |                       ^~~~~~~~
../tools/termios_linux.h: At top level:
../tools/termios_linux.h:36:17: warning: ‘struct termios2’ declared inside parameter list will not be visible outside of this definition or declaration
   36 | #define termios termios2
      |                 ^~~~~~~~
../tools/termios_linux.h:116:48: note: in expansion of macro ‘termios’
  116 | static inline speed_t cfgetospeed(const struct termios *t)
      |                                                ^~~~~~~
../tools/termios_linux.h: In function ‘cfgetospeed’:
../tools/termios_linux.h:118:17: error: invalid use of undefined type ‘const struct termios2’
  118 |         return t->c_cflag & CBAUD;
      |                 ^~
../tools/termios_linux.h: At top level:
../tools/termios_linux.h:36:17: warning: ‘struct termios2’ declared inside parameter list will not be visible outside of this definition or declaration
   36 | #define termios termios2
      |                 ^~~~~~~~
../tools/termios_linux.h:121:38: note: in expansion of macro ‘termios’
  121 | static inline int cfsetospeed(struct termios *t, speed_t s)
      |                                      ^~~~~~~
../tools/termios_linux.h: In function ‘cfsetospeed’:
../tools/termios_linux.h:128:10: error: invalid use of undefined type ‘struct termios2’
  128 |         t->c_cflag &= ~CBAUD;
      |          ^~
../tools/termios_linux.h:129:10: error: invalid use of undefined type ‘struct termios2’
  129 |         t->c_cflag |= s;
      |          ^~
...

Reproducible: Always

Comment 1 Florian Weimer 2025-06-27 09:35:27 UTC
This looks like an attempt in uboot-tools to use the termios2 kernel interfaces with the old glibc headers. Quoting the uboot-tools header:

/*
 * We need to use raw TCGETS2/TCSETS2 or TCGETS/TCSETS ioctls with the BOTHER
 * flag in struct termios2/termios, defined in Linux headers <asm/ioctls.h>
 * (included by <sys/ioctl.h>) and <asm/termbits.h>. Since these headers
 * conflict with glibc's header file <termios.h>, it is not possible to use
 * libc's termios functions and we need to reimplement them via ioctl() calls.
 *
 * An arbitrary baudrate is supported when the macro BOTHER is defined. The
 * baudrate value itself is then stored into the c_ospeed and c_ispeed members.
 * If ioctls TCGETS2/TCSETS2 are defined and supported then these fields are
 * present in struct termios2, otherwise these fields are present in struct
 * termios.
 *
 * Note that the Bnnn constants from <termios.h> need not be compatible with Bnnn
 * constants from <asm/termbits.h>.
 */

If the uboot-tools developers have suggestions how we can make the porting easier for them, maybe they can suggest that on libc-alpha?

Comment 2 Peter Robinson 2025-06-27 09:56:34 UTC
I'll reach out to upstream

Comment 3 Javier Martinez Canillas 2025-06-27 14:00:27 UTC
I've posted an RFC patch for u-boot: https://lists.denx.de/pipermail/u-boot/2025-June/593131.html

The problem as I understand it is that the PowerPC architecture does not define a struct termios2 as is the case for other architectures.

In https://elixir.bootlin.com/linux/v6.16-rc3/source/arch/powerpc/include/uapi/asm/termbits.h it says:

#define NCCS 19
struct termios {
	tcflag_t c_iflag;		/* input mode flags */
	tcflag_t c_oflag;		/* output mode flags */
	tcflag_t c_cflag;		/* control mode flags */
	tcflag_t c_lflag;		/* local mode flags */
	cc_t c_cc[NCCS];		/* control characters */
	cc_t c_line;			/* line discipline (== c_cc[19]) */
	speed_t c_ispeed;		/* input speed */
	speed_t c_ospeed;		/* output speed */
};

/* For PowerPC the termios and ktermios are the same */

struct ktermios {
	tcflag_t c_iflag;		/* input mode flags */
	tcflag_t c_oflag;		/* output mode flags */
	tcflag_t c_cflag;		/* control mode flags */
	tcflag_t c_lflag;		/* local mode flags */
	cc_t c_cc[NCCS];		/* control characters */
	cc_t c_line;			/* line discipline (== c_cc[19]) */
	speed_t c_ispeed;		/* input speed */
	speed_t c_ospeed;		/* output speed */
};

while all other architectures have a legacy struct termios and a struct termios2 that is the same than struct ktermios:

https://elixir.bootlin.com/linux/v6.16-rc3/source/include/uapi/asm-generic/termbits.h

#define NCCS 19
struct termios {
	tcflag_t c_iflag;		/* input mode flags */
	tcflag_t c_oflag;		/* output mode flags */
	tcflag_t c_cflag;		/* control mode flags */
	tcflag_t c_lflag;		/* local mode flags */
	cc_t c_line;			/* line discipline */
	cc_t c_cc[NCCS];		/* control characters */
};

struct termios2 {
	tcflag_t c_iflag;		/* input mode flags */
	tcflag_t c_oflag;		/* output mode flags */
	tcflag_t c_cflag;		/* control mode flags */
	tcflag_t c_lflag;		/* local mode flags */
	cc_t c_line;			/* line discipline */
	cc_t c_cc[NCCS];		/* control characters */
	speed_t c_ispeed;		/* input speed */
	speed_t c_ospeed;		/* output speed */
};

struct ktermios {
	tcflag_t c_iflag;		/* input mode flags */
	tcflag_t c_oflag;		/* output mode flags */
	tcflag_t c_cflag;		/* control mode flags */
	tcflag_t c_lflag;		/* local mode flags */
	cc_t c_line;			/* line discipline */
	cc_t c_cc[NCCS];		/* control characters */
	speed_t c_ispeed;		/* input speed */
	speed_t c_ospeed;		/* output speed */
};

Given that the u-boot header that Florian mentioned, includes the kernel headers, then of course there's no struct termios2 for PowerPC.

Comment 4 Javier Martinez Canillas 2025-06-27 14:04:01 UTC
Dan also mentioned this glibc https://sourceware.org/git/?p=glibc.git;a=commit;h=5f54d8bc48983bed844c02e1fe614ad223e78838

But AFAICT that change is not completely correct because is defining the TCGETS2/TCSETS*2 ioctls but using a struct termios2
that is not defined for PowerPC. Unless the #include <asm/ioctls.h> somehow includes the asm-generic headers that define the
struct termios2 ?

Comment 5 Florian Weimer 2025-06-30 14:00:57 UTC
(In reply to Javier Martinez Canillas from comment #4)
> Dan also mentioned this glibc
> https://sourceware.org/git/?p=glibc.git;a=commit;
> h=5f54d8bc48983bed844c02e1fe614ad223e78838
> 
> But AFAICT that change is not completely correct because is defining the
> TCGETS2/TCSETS*2 ioctls but using a struct termios2
> that is not defined for PowerPC. Unless the #include <asm/ioctls.h> somehow
> includes the asm-generic headers that define the
> struct termios2 ?

None of this should be necessary with current glibc (at least I hope so) because it's now termios2-based on all architectures.  We could define _LIBC_LINUX_TERMIOS2 in <features.h> to help u-boot to help to disable the compatibility hacks.

Comment 6 Javier Martinez Canillas 2025-07-01 11:22:24 UTC
(In reply to Florian Weimer from comment #5)
> (In reply to Javier Martinez Canillas from comment #4)
> > Dan also mentioned this glibc
> > https://sourceware.org/git/?p=glibc.git;a=commit;
> > h=5f54d8bc48983bed844c02e1fe614ad223e78838
> > 
> > But AFAICT that change is not completely correct because is defining the
> > TCGETS2/TCSETS*2 ioctls but using a struct termios2
> > that is not defined for PowerPC. Unless the #include <asm/ioctls.h> somehow
> > includes the asm-generic headers that define the
> > struct termios2 ?
> 
> None of this should be necessary with current glibc (at least I hope so)
> because it's now termios2-based on all architectures.  We could define
> _LIBC_LINUX_TERMIOS2 in <features.h> to help u-boot to help to disable the
> compatibility hacks.

I'm confused, but who defines the struct termios2 for the PowerPC architecture?

You said that current glibc it is now termios2-based on all architectures, but
I couldn't find where is defined for PowerPC.

Comment 7 Florian Weimer 2025-07-01 11:35:27 UTC
Hmm. I missed the incorrect definition problem. I raised it on libc-alpha. Hopefully it's just a typo, and the constant should use struct termios.

Comment 8 Javier Martinez Canillas 2025-07-01 11:44:49 UTC
(In reply to Florian Weimer from comment #7)
> Hmm. I missed the incorrect definition problem. I raised it on libc-alpha.
> Hopefully it's just a typo, and the constant should use struct termios.

Yes, that should work too.

Comment 9 Dan Horák 2025-07-01 11:47:49 UTC
for the record, https://sourceware.org/pipermail/libc-alpha/2025-July/168322.html

Comment 10 Javier Martinez Canillas 2025-07-01 23:13:46 UTC
What is mentioned in https://sourceware.org/pipermail/libc-alpha/2025-July/168339.html is not accurate AFAICT:

"<linux/termios.h> defines it, but that header conflicts with <termios.h>."

but what I see in the Linux kernel source repo is the following:

$ make x86_64_defconfig prepare modules_prepare

$ cat ./arch/x86/include/generated/uapi/asm/termbits.h
#include <asm-generic/termbits.h>

$ grep "struct termios2" include/uapi/asm-generic/termbits.h 
19:struct termios2 {

$ head -n 40 arch/powerpc/include/uapi/asm/termbits.h
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
#ifndef _ASM_POWERPC_TERMBITS_H
#define _ASM_POWERPC_TERMBITS_H

/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <asm-generic/termbits-common.h>

typedef unsigned int    tcflag_t;

/*
 * termios type and macro definitions.  Be careful about adding stuff
 * to this file since it's used in GNU libc and there are strict rules
 * concerning namespace pollution.
 */

#define NCCS 19
struct termios {
        tcflag_t c_iflag;               /* input mode flags */
        tcflag_t c_oflag;               /* output mode flags */
        tcflag_t c_cflag;               /* control mode flags */
        tcflag_t c_lflag;               /* local mode flags */
        cc_t c_cc[NCCS];                /* control characters */
        cc_t c_line;                    /* line discipline (== c_cc[19]) */
        speed_t c_ispeed;               /* input speed */
        speed_t c_ospeed;               /* output speed */
};

/* For PowerPC the termios and ktermios are the same */

struct ktermios {
        tcflag_t c_iflag;               /* input mode flags */
        tcflag_t c_oflag;               /* output mode flags */
        tcflag_t c_cflag;               /* control mode flags */
        tcflag_t c_lflag;               /* local mode flags */

Comment 11 Javier Martinez Canillas 2025-07-01 23:20:40 UTC
In other words, struct termios and struct termios2 (if defined for the arch) are defined in <asm/termbits.h>,
which for x86 is just <asm-generic/termbits.h> and powerpc has its own that does not define a struct termios2.


Note You need to log in before you can comment on or make changes to this bug.