scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit 6212cd97ef3b5311a8245131e8bf5f9957e4fd67
parent 73b42fa96c7f6580d0cc18a4611c620e3ec28e44
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Fri,  8 May 2026 15:34:16 +0200

libmach: Encode number of bits in OBJ()

Some formats have different versions based in being a 32 or 64
bit version, and deriving it from the arch has corner cases and
it requires continous maintainance.

Diffstat:
Minclude/scc/bits/scc/mach.h | 11+++++++++--
Msrc/libmach/coff32/coff32archs.c | 4++--
Msrc/libmach/elf/elfarchs.c | 2+-
Msrc/libmach/elf/elfprobe.c | 7++++---
4 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/include/scc/bits/scc/mach.h b/include/scc/bits/scc/mach.h @@ -6,10 +6,11 @@ #undef BIG_ENDIAN #define NBYTES 32 -#define OBJ(format,arch,order) ((order) << 10 | (arch) << 5 | (format)) +#define OBJ(fmt,arch,order,bits) ((bits) << 11 | (order) << 10 | (arch) << 5 | (fmt)) #define FORMAT(t) ((t) & 0x1f) #define ARCH(t) (((t) >> 5) & 0x1f) -#define ORDER(t) (((t) >> 10) & 0x1f) +#define ORDER(t) (((t) >> 10) & 0x1) +#define BITS(t) (((t) >> 11) & 0x3) #define objfmt(o) FORMAT((o)->type) typedef struct section Section; @@ -24,6 +25,12 @@ enum objformat { NFORMATS, }; +enum objbits { + OBJ16, + OBJ32, + OBJ64, +}; + enum objarch { ARCH286, ARCH386, diff --git a/src/libmach/coff32/coff32archs.c b/src/libmach/coff32/coff32archs.c @@ -6,7 +6,7 @@ #include "../libmach.h" struct arch coff32archs[] = { - {"coff-i386", "\x4c\x01", OBJ(COFF32, ARCH386, LITTLE_ENDIAN), 0x0105}, - {"coff-z80", "\x5a\x80", OBJ(COFF32, ARCHZ80, LITTLE_ENDIAN), 0x3105}, + {"coff-i386", "\x4c\x01", OBJ(COFF32, ARCH386, LITTLE_ENDIAN, OBJ32), 0x0105}, + {"coff-z80", "\x5a\x80", OBJ(COFF32, ARCHZ80, LITTLE_ENDIAN, OBJ32), 0x3105}, NULL, }; diff --git a/src/libmach/elf/elfarchs.c b/src/libmach/elf/elfarchs.c @@ -13,7 +13,7 @@ struct arch elfarchs[] = { .name = "elf-amd64", .mach = EM_X86_64, .endian = ELFDATA2LSB, - .type = OBJ(ELF, ARCHAMD64, LITTLE_ENDIAN), + .type = OBJ(ELF, ARCHAMD64, LITTLE_ENDIAN, OBJ64), .is32 = 0, }, NULL, diff --git a/src/libmach/elf/elfprobe.c b/src/libmach/elf/elfprobe.c @@ -11,13 +11,14 @@ int elfprobe(unsigned char *buf, char **name) { - int arch, data, endian; + int arch, data, endian, bits; struct elfhdr32 hdr; struct arch *ap; data = buf[EI_DATA]; endian = (data == ELFDATA2LSB) ? LITTLE_ENDIAN : BIG_ENDIAN; arch = (buf[EI_CLASS] == ELFCLASS32) ? ARCHUNK32 : ARCHUNK64; + bits = (buf[EI_CLASS] == ELFCLASS32) ? OBJ32 : OBJ64; unpack(endian, buf, @@ -36,7 +37,7 @@ elfprobe(unsigned char *buf, char **name) } for (ap = elfarchs; ap->name; ap++) { - if (ap->mach == hdr.e_machine && ap->endian == data) { + if (ap->mach == hdr.e_machine && ap->endian == data) { if (name) *name = ap->name; return ap->type; @@ -46,5 +47,5 @@ elfprobe(unsigned char *buf, char **name) if (name) *name = "elf-unknown"; - return OBJ(ELF, arch, endian); + return OBJ(ELF, arch, endian, bits); }