1 // Copyright 2019 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/snapshot/embedded/platform-embedded-file-writer-aix.h"
6 
7 #include "src/objects/code.h"
8 
9 namespace v8 {
10 namespace internal {
11 
12 #define SYMBOL_PREFIX ""
13 
14 namespace {
15 
DirectiveAsString(DataDirective directive)16 const char* DirectiveAsString(DataDirective directive) {
17   switch (directive) {
18     case kByte:
19       return ".byte";
20     case kLong:
21       return ".long";
22     case kQuad:
23       return ".llong";
24     default:
25       UNREACHABLE();
26   }
27 }
28 
29 }  // namespace
30 
SectionText()31 void PlatformEmbeddedFileWriterAIX::SectionText() {
32   fprintf(fp_, ".csect [GL], 6\n");
33 }
34 
SectionData()35 void PlatformEmbeddedFileWriterAIX::SectionData() {
36   fprintf(fp_, ".csect .data[RW]\n");
37 }
38 
SectionRoData()39 void PlatformEmbeddedFileWriterAIX::SectionRoData() {
40   fprintf(fp_, ".csect[RO]\n");
41 }
42 
DeclareUint32(const char* name, uint32_t value)43 void PlatformEmbeddedFileWriterAIX::DeclareUint32(const char* name,
44                                                   uint32_t value) {
45   DeclareSymbolGlobal(name);
46   fprintf(fp_, ".align 2\n");
47   fprintf(fp_, "%s:\n", name);
48   IndentedDataDirective(kLong);
49   fprintf(fp_, "%d\n", value);
50   Newline();
51 }
52 
DeclarePointerToSymbol(const char* name, const char* target)53 void PlatformEmbeddedFileWriterAIX::DeclarePointerToSymbol(const char* name,
54                                                            const char* target) {
55   AlignToCodeAlignment();
56   DeclareLabel(name);
57   fprintf(fp_, "  %s %s\n", DirectiveAsString(PointerSizeDirective()), target);
58   Newline();
59 }
60 
DeclareSymbolGlobal(const char* name)61 void PlatformEmbeddedFileWriterAIX::DeclareSymbolGlobal(const char* name) {
62   // These symbols are not visible outside of the final binary, this allows for
63   // reduced binary size, and less work for the dynamic linker.
64   fprintf(fp_, ".globl %s, hidden\n", name);
65 }
66 
AlignToCodeAlignment()67 void PlatformEmbeddedFileWriterAIX::AlignToCodeAlignment() {
68 #if V8_TARGET_ARCH_X64
69   // On x64 use 64-bytes code alignment to allow 64-bytes loop header alignment.
70   STATIC_ASSERT((1 << 6) >= kCodeAlignment);
71   fprintf(fp_, ".align 6\n");
72 #elif V8_TARGET_ARCH_PPC64
73   // 64 byte alignment is needed on ppc64 to make sure p10 prefixed instructions
74   // don't cross 64-byte boundaries.
75   STATIC_ASSERT((1 << 6) >= kCodeAlignment);
76   fprintf(fp_, ".align 6\n");
77 #else
78   STATIC_ASSERT((1 << 5) >= kCodeAlignment);
79   fprintf(fp_, ".align 5\n");
80 #endif
81 }
82 
AlignToDataAlignment()83 void PlatformEmbeddedFileWriterAIX::AlignToDataAlignment() {
84   STATIC_ASSERT((1 << 3) >= Code::kMetadataAlignment);
85   fprintf(fp_, ".align 3\n");
86 }
87 
Comment(const char* string)88 void PlatformEmbeddedFileWriterAIX::Comment(const char* string) {
89   fprintf(fp_, "// %s\n", string);
90 }
91 
DeclareLabel(const char* name)92 void PlatformEmbeddedFileWriterAIX::DeclareLabel(const char* name) {
93   // .global is required on AIX, if the label is used/referenced in another file
94   // later to be linked.
95   fprintf(fp_, ".globl %s\n", name);
96   fprintf(fp_, "%s:\n", name);
97 }
98 
SourceInfo(int fileid, const char* filename, int line)99 void PlatformEmbeddedFileWriterAIX::SourceInfo(int fileid, const char* filename,
100                                                int line) {
101   fprintf(fp_, ".xline %d, \"%s\"\n", line, filename);
102 }
103 
104 // TODO(mmarchini): investigate emitting size annotations for AIX
DeclareFunctionBegin(const char* name, uint32_t size)105 void PlatformEmbeddedFileWriterAIX::DeclareFunctionBegin(const char* name,
106                                                          uint32_t size) {
107   Newline();
108   if (ENABLE_CONTROL_FLOW_INTEGRITY_BOOL) {
109     DeclareSymbolGlobal(name);
110   }
111   fprintf(fp_, ".csect %s[DS]\n", name);  // function descriptor
112   fprintf(fp_, "%s:\n", name);
113   fprintf(fp_, ".llong .%s, 0, 0\n", name);
114   SectionText();
115   fprintf(fp_, ".%s:\n", name);
116 }
117 
DeclareFunctionEnd(const char* name)118 void PlatformEmbeddedFileWriterAIX::DeclareFunctionEnd(const char* name) {}
119 
FilePrologue()120 void PlatformEmbeddedFileWriterAIX::FilePrologue() {}
121 
DeclareExternalFilename( int fileid, const char* filename)122 void PlatformEmbeddedFileWriterAIX::DeclareExternalFilename(
123     int fileid, const char* filename) {
124   // File name cannot be declared with an identifier on AIX.
125   // We use the SourceInfo method to emit debug info in
126   //.xline <line-number> <file-name> format.
127 }
128 
FileEpilogue()129 void PlatformEmbeddedFileWriterAIX::FileEpilogue() {}
130 
IndentedDataDirective( DataDirective directive)131 int PlatformEmbeddedFileWriterAIX::IndentedDataDirective(
132     DataDirective directive) {
133   return fprintf(fp_, "  %s ", DirectiveAsString(directive));
134 }
135 
ByteChunkDataDirective() const136 DataDirective PlatformEmbeddedFileWriterAIX::ByteChunkDataDirective() const {
137   // PPC uses a fixed 4 byte instruction set, using .long
138   // to prevent any unnecessary padding.
139   return kLong;
140 }
141 
142 #undef SYMBOL_PREFIX
143 
144 }  // namespace internal
145 }  // namespace v8
146