@@ -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+
28072834static 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