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
9namespace v8 {
10namespace internal {
11
12#define SYMBOL_PREFIX ""
13
14namespace {
15
16const 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
31void PlatformEmbeddedFileWriterAIX::SectionText() {
32  fprintf(fp_, ".csect [GL], 6\n");
33}
34
35void PlatformEmbeddedFileWriterAIX::SectionData() {
36  fprintf(fp_, ".csect .data[RW]\n");
37}
38
39void PlatformEmbeddedFileWriterAIX::SectionRoData() {
40  fprintf(fp_, ".csect[RO]\n");
41}
42
43void 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
53void 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
61void 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
67void 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
83void PlatformEmbeddedFileWriterAIX::AlignToDataAlignment() {
84  STATIC_ASSERT((1 << 3) >= Code::kMetadataAlignment);
85  fprintf(fp_, ".align 3\n");
86}
87
88void PlatformEmbeddedFileWriterAIX::Comment(const char* string) {
89  fprintf(fp_, "// %s\n", string);
90}
91
92void 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
99void 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
105void 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
118void PlatformEmbeddedFileWriterAIX::DeclareFunctionEnd(const char* name) {}
119
120void PlatformEmbeddedFileWriterAIX::FilePrologue() {}
121
122void 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
129void PlatformEmbeddedFileWriterAIX::FileEpilogue() {}
130
131int PlatformEmbeddedFileWriterAIX::IndentedDataDirective(
132    DataDirective directive) {
133  return fprintf(fp_, "  %s ", DirectiveAsString(directive));
134}
135
136DataDirective 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