Commit | Line | Data |
---|---|---|
5922befa LM |
1 | /* Support for AMDHSA ELF. |
2 | ||
4e5106e6 LM |
3 | Copyright (C) 2019-2020 Free Software Foundation, Inc. |
4 | Copyright (C) 2019-2020 Advanced Micro Devices, Inc. All rights reserved. | |
5922befa LM |
5 | |
6 | This file is part of GDB. | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 3 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
20 | ||
21 | #include "sysdep.h" | |
22 | #include "bfd.h" | |
23 | #include "libbfd.h" | |
24 | #include "elf-bfd.h" | |
25 | #include "elf/amdgcn.h" | |
26 | ||
27 | #include <string.h> | |
28 | ||
29 | ||
30 | static unsigned int | |
31 | bfd_amdgcn_get_mach_from_notes (bfd *abfd) | |
32 | { | |
33 | asection * note_section; | |
34 | bfd_size_type buffer_size; | |
35 | bfd_byte * ptr, * end, * buffer = NULL; | |
36 | unsigned int mach = 0; | |
37 | ||
38 | note_section = bfd_get_section_by_name (abfd, ".note"); | |
39 | if (note_section == NULL) | |
40 | return 0; | |
41 | ||
42 | buffer_size = note_section->size; | |
43 | if (buffer_size == 0) | |
44 | return 0; | |
45 | ||
46 | if (!bfd_malloc_and_get_section (abfd, note_section, &buffer)) | |
47 | return 0; | |
48 | ||
49 | ptr = buffer; | |
50 | end = &buffer[buffer_size]; | |
51 | while (mach == 0 && buffer < end) | |
52 | { | |
53 | unsigned long namesz; | |
54 | unsigned long descsz; | |
55 | unsigned long type; | |
56 | ||
57 | if ((ptr + 12) >= end) | |
58 | break; | |
59 | ||
60 | namesz = bfd_get_32 (abfd, ptr); | |
61 | descsz = bfd_get_32 (abfd, ptr + 4); | |
62 | type = bfd_get_32 (abfd, ptr + 8); | |
63 | ||
64 | if (namesz == 4 && (ptr + 16) <= end | |
65 | && (!strcmp((char*) ptr + 12, "AMDGPU") | |
66 | || !strcmp((char*) ptr + 12, "AMD")) | |
67 | && type == NT_AMDGPU_HSA_ISA) | |
68 | { | |
69 | unsigned int major, minor, patch; | |
70 | ||
71 | major = bfd_get_32 (abfd, ptr + 20); | |
72 | minor = bfd_get_32 (abfd, ptr + 24); | |
73 | patch = bfd_get_32 (abfd, ptr + 28); | |
74 | ||
75 | switch (major * 100 + minor * 10 + patch) | |
76 | { | |
77 | case 801: mach = bfd_mach_amdgcn_gfx801; break; | |
78 | case 802: mach = bfd_mach_amdgcn_gfx802; break; | |
79 | case 803: mach = bfd_mach_amdgcn_gfx803; break; | |
80 | case 810: mach = bfd_mach_amdgcn_gfx810; break; | |
81 | case 900: mach = bfd_mach_amdgcn_gfx900; break; | |
82 | case 902: mach = bfd_mach_amdgcn_gfx902; break; | |
83 | case 904: mach = bfd_mach_amdgcn_gfx904; break; | |
84 | case 906: mach = bfd_mach_amdgcn_gfx906; break; | |
85 | case 908: mach = bfd_mach_amdgcn_gfx908; break; | |
86 | case 909: mach = bfd_mach_amdgcn_gfx909; break; | |
87 | default: mach = bfd_mach_amdgcn_unknown; break; | |
88 | } | |
89 | } | |
90 | ||
91 | ptr += 12 + ((namesz + 3) & ~3) + ((descsz + 3) & ~3); | |
92 | } | |
93 | ||
94 | ||
95 | if (buffer != NULL) | |
96 | free (buffer); | |
97 | ||
98 | return mach; | |
99 | } | |
100 | ||
101 | static bfd_boolean | |
102 | elf64_amdgcn_object_p (bfd *abfd) | |
103 | { | |
104 | unsigned int mach; | |
105 | ||
106 | if (elf_elfheader (abfd)->e_ident[EI_OSABI] != ELFOSABI_AMDGPU_HSA) | |
107 | return FALSE; | |
108 | ||
109 | if (elf_elfheader (abfd)->e_ident[EI_ABIVERSION] < 1) | |
110 | mach = bfd_amdgcn_get_mach_from_notes (abfd); | |
111 | else | |
112 | mach = elf_elfheader (abfd)->e_flags & EF_AMDGPU_MACH; | |
113 | ||
114 | bfd_default_set_arch_mach (abfd, bfd_arch_amdgcn, mach); | |
115 | return TRUE; | |
116 | } | |
117 | ||
118 | ||
119 | #define TARGET_LITTLE_SYM amdgcn_elf64_le_vec | |
120 | #define TARGET_LITTLE_NAME "elf64-amdgcn" | |
121 | #define ELF_ARCH bfd_arch_amdgcn | |
122 | #define ELF_TARGET_ID AMDGCN_ELF_DATA | |
123 | #define ELF_MACHINE_CODE EM_AMDGPU | |
124 | #define ELF_OSABI ELFOSABI_AMDGPU_HSA | |
125 | #define ELF_MAXPAGESIZE 0x10000 /* 64KB */ | |
126 | #define ELF_COMMONPAGESIZE 0x1000 /* 4KB */ | |
127 | ||
128 | #define bfd_elf64_bfd_reloc_type_lookup \ | |
129 | bfd_default_reloc_type_lookup | |
130 | #define bfd_elf64_bfd_reloc_name_lookup \ | |
131 | _bfd_norelocs_bfd_reloc_name_lookup | |
132 | ||
133 | #define elf_backend_object_p \ | |
134 | elf64_amdgcn_object_p | |
135 | ||
136 | #include "elf64-target.h" |