Skip to content

Commit b45cea5

Browse files
committed
Update bsd notes
freebsd 13 must not have note section. freebsd 14 must have note section. also added version info.
1 parent b427545 commit b45cea5

File tree

1 file changed

+55
-15
lines changed

1 file changed

+55
-15
lines changed

tccelf.c

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2803,23 +2803,62 @@ static void create_arm_attribute_section(TCCState *s1)
28032803
}
28042804
#endif
28052805

2806-
#if TARGETOS_OpenBSD || TARGETOS_NetBSD
2806+
#if TARGETOS_OpenBSD || TARGETOS_NetBSD || TARGETOS_FreeBSD
2807+
#include <sys/utsname.h>
2808+
2809+
static void fill_bsd_note(Section *s, int type,
2810+
const char *value, uint32_t data)
2811+
{
2812+
unsigned long offset = 0;
2813+
char *ptr;
2814+
ElfW(Nhdr) *note;
2815+
int align = s->sh_addralign;
2816+
2817+
/* check if type present */
2818+
while (offset + sizeof(ElfW(Nhdr)) < s->data_offset) {
2819+
note = (ElfW(Nhdr) *) (s->data + offset);
2820+
if (note->n_type == type)
2821+
return;
2822+
offset += (sizeof(ElfW(Nhdr)) + note->n_namesz + note->n_descsz +
2823+
align - 1) & -align;
2824+
}
2825+
ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2826+
note = (ElfW(Nhdr) *) ptr;
2827+
note->n_namesz = 8;
2828+
note->n_descsz = 4;
2829+
note->n_type = type;
2830+
strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2831+
memcpy (ptr + sizeof(ElfW(Nhdr)) + 8, &data, 4);
2832+
}
2833+
28072834
static Section *create_bsd_note_section(TCCState *s1,
28082835
const char *name,
28092836
const char *value)
28102837
{
2811-
Section *s = find_section (s1, name);
2812-
2813-
if (s->data_offset == 0) {
2814-
char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2815-
ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2838+
Section *s;
2839+
unsigned int major = 0, minor = 0, patch = 0;
2840+
struct utsname uts;
28162841

2817-
s->sh_type = SHT_NOTE;
2818-
note->n_namesz = 8;
2819-
note->n_descsz = 4;
2820-
note->n_type = ELF_NOTE_OS_GNU;
2821-
strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2822-
}
2842+
if (!uname(&uts))
2843+
sscanf(uts.release, "%u.%u.%u", &major, &minor, &patch);
2844+
#if TARGETOS_FreeBSD
2845+
if (major < 14)
2846+
return NULL;
2847+
#endif
2848+
s = find_section (s1, name);
2849+
s->sh_type = SHT_NOTE;
2850+
#if TARGETOS_OpenBSD
2851+
fill_bsd_note(s, ELF_NOTE_OS_GNU, value, 0);
2852+
#elif TARGETOS_NetBSD
2853+
fill_bsd_note(s, 1 /* NT_NETBSD_IDENT_TAG */, value,
2854+
major * 100000000u + (minor % 100u) * 1000000u +
2855+
(patch % 10000u) * 100u);
2856+
#elif TARGETOS_FreeBSD
2857+
fill_bsd_note(s, 1 /* NT_FREEBSD_ABI_TAG */, value,
2858+
major * 100000u + (minor % 100u) * 1000u);
2859+
fill_bsd_note(s, 4 /* NT_FREEBSD_FEATURE_CTL */, value, 0);
2860+
fill_bsd_note(s, 2 /* NT_FREEBSD_NOINIT_TAG */, value, 0);
2861+
#endif
28232862
return s;
28242863
}
28252864
#endif
@@ -2853,12 +2892,13 @@ static int elf_output_file(TCCState *s1, const char *filename)
28532892
dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
28542893
#endif
28552894

2895+
#if TARGETOS_FreeBSD
2896+
dyninf.note = create_bsd_note_section (s1, ".note.tag", "FreeBSD");
2897+
#endif
2898+
28562899
#if TARGETOS_FreeBSD || TARGETOS_NetBSD
28572900
dyninf.roinf = NULL;
28582901
#endif
2859-
#if TARGETOS_FreeBSD
2860-
dyninf.note = find_section (s1, ".note.tag");
2861-
#endif
28622902

28632903
/* if linking, also link in runtime libraries (libc, libgcc, etc.) */
28642904
tcc_add_runtime(s1);

0 commit comments

Comments
 (0)