freebsd 13 must not have note section. freebsd 14 must have note section. also added version info.
Unified · Split
| @@ -2803,23 +2803,62 @@ static void create_arm_attribute_section(TCCState *s1) · 2802 unmodified lines | ||
| 2803 | 2803 | } |
| 2804 | 2804 | #endif |
| 2805 | 2805 | |
| 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 | + | |
| 2807 | 2834 | static Section *create_bsd_note_section(TCCState *s1, |
| 2808 | 2835 | const char *name, |
| 2809 | 2836 | const char *value) |
| 2810 | 2837 | { |
| 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; | |
| 2816 | 2841 | |
| 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 | |
| 2823 | 2862 | return s; |
| 2824 | 2863 | } |
| 2825 | 2864 | #endif |
| @@ -2853,12 +2892,13 @@ static int elf_output_file(TCCState *s1, const char *filename) · 27 unmodified lines | ||
| 2853 | 2892 | dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD"); |
| 2854 | 2893 | #endif |
| 2855 | 2894 | |
| 2895 | +#if TARGETOS_FreeBSD | |
| 2896 | + dyninf.note = create_bsd_note_section (s1, ".note.tag", "FreeBSD"); | |
| 2897 | +#endif | |
| 2898 | + | |
| 2856 | 2899 | #if TARGETOS_FreeBSD || TARGETOS_NetBSD |
| 2857 | 2900 | dyninf.roinf = NULL; |
| 2858 | 2901 | #endif |
| 2859 | −#if TARGETOS_FreeBSD | |
| 2860 | − dyninf.note = find_section (s1, ".note.tag"); | |
| 2861 | −#endif | |
| 2862 | 2902 | |
| 2863 | 2903 | /* if linking, also link in runtime libraries (libc, libgcc, etc.) */ |
| 2864 | 2904 | tcc_add_runtime(s1); |