1 /*
2  * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 
26 package jdk.tools.jaotc;
27 
28 import jdk.tools.jaotc.binformat.BinaryContainer;
29 import jdk.tools.jaotc.binformat.Symbol;
30 
31 import jdk.vm.ci.code.site.Call;
32 
33 final class ForeignGotCallSiteRelocationSymbol extends CallSiteRelocationSymbol {
34 
ForeignGotCallSiteRelocationSymbol(CompiledMethodInfo mi, Call call, CallSiteRelocationInfo callSiteRelocation, DataBuilder dataBuilder)35     ForeignGotCallSiteRelocationSymbol(CompiledMethodInfo mi, Call call, CallSiteRelocationInfo callSiteRelocation, DataBuilder dataBuilder) {
36         super(createPltSymbol(dataBuilder, mi, call, callSiteRelocation));
37     }
38 
createPltSymbol(DataBuilder dataBuilder, CompiledMethodInfo mi, Call call, CallSiteRelocationInfo callSiteRelocation)39     private static Symbol createPltSymbol(DataBuilder dataBuilder, CompiledMethodInfo mi, Call call, CallSiteRelocationInfo callSiteRelocation) {
40         BinaryContainer binaryContainer = dataBuilder.getBinaryContainer();
41         String vmSymbolName = callSiteRelocation.targetSymbol;
42 
43         // Add relocation to GOT cell for call resolution jump.
44         String pltSymbolName = "plt." + vmSymbolName;
45         Symbol pltSymbol = binaryContainer.getSymbol(pltSymbolName);
46 
47         if (pltSymbol == null) {
48             String gotSymbolName = "got." + vmSymbolName;
49             Symbol gotSymbol = binaryContainer.getGotSymbol(gotSymbolName);
50             assert gotSymbol != null : "undefined VM got symbol '" + gotSymbolName + "' for call at " + call.pcOffset + " in " + mi.getMethodInfo().getSymbolName();
51 
52             // Generate PLT jump (do it only once).
53             final int pltStartOffset = binaryContainer.getCodeContainer().getByteStreamSize();
54             final int pltEndOffset = pltStartOffset + addPltJump(dataBuilder);
55 
56             // Link GOT cell to PLT jump.
57             pltSymbol = createCodeContainerSymbol(binaryContainer, pltSymbolName, pltStartOffset);
58             addExternalPltToGotRelocation(binaryContainer, gotSymbol, pltEndOffset);
59         }
60 
61         return pltSymbol;
62     }
63 
addPltJump(DataBuilder dataBuilder)64     private static int addPltJump(DataBuilder dataBuilder) {
65         ELFMacroAssembler masm = ELFMacroAssembler.getELFMacroAssembler(dataBuilder.getBackend().getTarget(), dataBuilder.getBackend().getRuntime().getOptions());
66         byte[] code = masm.getPLTJumpCode(); // It includes alignment nops.
67         int size = masm.currentEndOfInstruction();
68         dataBuilder.getBinaryContainer().appendCodeBytes(code, 0, code.length);
69         return size;
70     }
71 
72 }
73