@@ -107,6 +107,7 @@ pub fn emit(
107107 mir .body [nav_reloc .reloc .label ],
108108 body_end - Instruction .size * (1 + nav_reloc .reloc .label ),
109109 nav_reloc .reloc .addend ,
110+ if (ip .getNav (nav_reloc .nav ).getExtern (ip )) | _ | .got_load else .direct ,
110111 );
111112 for (mir .uav_relocs ) | uav_reloc | try emitReloc (
112113 lf ,
@@ -124,6 +125,7 @@ pub fn emit(
124125 mir .body [uav_reloc .reloc .label ],
125126 body_end - Instruction .size * (1 + uav_reloc .reloc .label ),
126127 uav_reloc .reloc .addend ,
128+ .direct ,
127129 );
128130 for (mir .lazy_relocs ) | lazy_reloc | try emitReloc (
129131 lf ,
@@ -140,6 +142,7 @@ pub fn emit(
140142 mir .body [lazy_reloc .reloc .label ],
141143 body_end - Instruction .size * (1 + lazy_reloc .reloc .label ),
142144 lazy_reloc .reloc .addend ,
145+ .direct ,
143146 );
144147 for (mir .global_relocs ) | global_reloc | try emitReloc (
145148 lf ,
@@ -154,6 +157,7 @@ pub fn emit(
154157 mir .body [global_reloc .reloc .label ],
155158 body_end - Instruction .size * (1 + global_reloc .reloc .label ),
156159 global_reloc .reloc .addend ,
160+ .direct ,
157161 );
158162 const literal_reloc_offset : i19 = @intCast (mir .epilogue .len + literals_align_gap );
159163 for (mir .literal_relocs ) | literal_reloc | {
@@ -188,6 +192,7 @@ fn emitReloc(
188192 instruction : Instruction ,
189193 offset : u32 ,
190194 addend : u64 ,
195+ kind : enum { direct , got_load },
191196) ! void {
192197 const gpa = zcu .gpa ;
193198 switch (instruction .decode ()) {
@@ -198,11 +203,20 @@ fn emitReloc(
198203 const r_type : std.elf.R_AARCH64 = switch (decoded .decode ()) {
199204 else = > unreachable ,
200205 .pc_relative_addressing = > | pc_relative_addressing | switch (pc_relative_addressing .group .op ) {
201- .adr = > .ADR_PREL_LO21 ,
202- .adrp = > .ADR_PREL_PG_HI21 ,
206+ .adr = > switch (kind ) {
207+ .direct = > .ADR_PREL_LO21 ,
208+ .got_load = > unreachable ,
209+ },
210+ .adrp = > switch (kind ) {
211+ .direct = > .ADR_PREL_PG_HI21 ,
212+ .got_load = > .ADR_GOT_PAGE ,
213+ },
203214 },
204215 .add_subtract_immediate = > | add_subtract_immediate | switch (add_subtract_immediate .group .op ) {
205- .add = > .ADD_ABS_LO12_NC ,
216+ .add = > switch (kind ) {
217+ .direct = > .ADD_ABS_LO12_NC ,
218+ .got_load = > unreachable ,
219+ },
206220 .sub = > unreachable ,
207221 },
208222 };
@@ -223,7 +237,10 @@ fn emitReloc(
223237 .offset = offset ,
224238 .target = sym_index ,
225239 .addend = @bitCast (addend ),
226- .type = .page ,
240+ .type = switch (kind ) {
241+ .direct = > .page ,
242+ .got_load = > .got_load_page ,
243+ },
227244 .meta = .{
228245 .pcrel = true ,
229246 .has_subtractor = false ,
@@ -238,7 +255,10 @@ fn emitReloc(
238255 .offset = offset ,
239256 .target = sym_index ,
240257 .addend = @bitCast (addend ),
241- .type = .pageoff ,
258+ .type = switch (kind ) {
259+ .direct = > .pageoff ,
260+ .got_load = > .got_load_pageoff ,
261+ },
242262 .meta = .{
243263 .pcrel = false ,
244264 .has_subtractor = false ,
@@ -285,20 +305,39 @@ fn emitReloc(
285305 const r_type : std.elf.R_AARCH64 = switch (decoded .decode ().register_unsigned_immediate .decode ()) {
286306 .integer = > | integer | switch (integer .decode ()) {
287307 .unallocated , .prfm = > unreachable ,
288- .strb , .ldrb , .ldrsb = > .LDST8_ABS_LO12_NC ,
289- .strh , .ldrh , .ldrsh = > .LDST16_ABS_LO12_NC ,
290- .ldrsw = > .LDST32_ABS_LO12_NC ,
291- inline .str , .ldr = > | encoded | switch (encoded .sf ) {
308+ .strb , .ldrb , .ldrsb = > switch (kind ) {
309+ .direct = > .LDST8_ABS_LO12_NC ,
310+ .got_load = > unreachable ,
311+ },
312+ .strh , .ldrh , .ldrsh = > switch (kind ) {
313+ .direct = > .LDST16_ABS_LO12_NC ,
314+ .got_load = > unreachable ,
315+ },
316+ .ldrsw = > switch (kind ) {
317+ .direct = > .LDST32_ABS_LO12_NC ,
318+ .got_load = > unreachable ,
319+ },
320+ inline .str , .ldr = > | encoded , mnemonic | switch (encoded .sf ) {
292321 .word = > .LDST32_ABS_LO12_NC ,
293- .doubleword = > .LDST64_ABS_LO12_NC ,
322+ .doubleword = > switch (kind ) {
323+ .direct = > .LDST64_ABS_LO12_NC ,
324+ .got_load = > switch (mnemonic ) {
325+ else = > comptime unreachable ,
326+ .str = > unreachable ,
327+ .ldr = > .LD64_GOT_LO12_NC ,
328+ },
329+ },
294330 },
295331 },
296- .vector = > | vector | switch (vector .group .opc1 .decode (vector .group .size )) {
297- .byte = > .LDST8_ABS_LO12_NC ,
298- .half = > .LDST16_ABS_LO12_NC ,
299- .single = > .LDST32_ABS_LO12_NC ,
300- .double = > .LDST64_ABS_LO12_NC ,
301- .quad = > .LDST128_ABS_LO12_NC ,
332+ .vector = > | vector | switch (kind ) {
333+ .direct = > switch (vector .group .opc1 .decode (vector .group .size )) {
334+ .byte = > .LDST8_ABS_LO12_NC ,
335+ .half = > .LDST16_ABS_LO12_NC ,
336+ .single = > .LDST32_ABS_LO12_NC ,
337+ .double = > .LDST64_ABS_LO12_NC ,
338+ .quad = > .LDST128_ABS_LO12_NC ,
339+ },
340+ .got_load = > unreachable ,
302341 },
303342 };
304343 try atom .addReloc (gpa , .{
@@ -314,7 +353,10 @@ fn emitReloc(
314353 .offset = offset ,
315354 .target = sym_index ,
316355 .addend = @bitCast (addend ),
317- .type = .pageoff ,
356+ .type = switch (kind ) {
357+ .direct = > .pageoff ,
358+ .got_load = > .got_load_pageoff ,
359+ },
318360 .meta = .{
319361 .pcrel = false ,
320362 .has_subtractor = false ,
0 commit comments